package framework.forms;

import org.openqa.selenium.By;

import framework.GmailUtils;
import framework.catalog.CatalogOkpoForm;
import framework.elements.Button;
import framework.elements.Label;
import framework.elements.Link;
import framework.elements.TextBox;
import framework.partitions.BasePartition;
import framework.tables.BaseTable;

/**
 * Форма регистрации организации
 */
public class OrganizationRegisterForm extends BaseOrganizationForm{

	/** Базовый конструктор.
	 */
	protected OrganizationRegisterForm() {
		super(By.xpath("//div[@id='outerWrapper']//div[@id='emptyWhite']"), "Регистрация");
		browser.waitForPageToLoad();
	}

	private Button nextBtn = new Button(By.xpath("//div[@class='buttons_2']//input[@value='Далее']"), "Далее");
	//Вкладка Регистрация пользователя
	private Label selectedRegUserTab = new Label(By.xpath("//form[@id='userRegistrationForm']/div[@id='tabtable']//li[@class='active']/span[contains(.,'Регистрация пользователя')]"), "Активная вкладка: Регистрация пользователя");
	private Button zaregistrirovat = new Button(By.xpath("//input[@value='Зарегистрировать']"), "Зарегистрировать");
	private Label warningRegMessage = new Label(By.xpath("//div[contains(@class,'jquery-msgbox-wrapper')]/form"), "Сообщение при регистрации");
	private Button continueBtn = new Button(By.xpath("//button[contains(.,'Продолжить')]"), "Продолжить");
	private final String expectedRegText = "//span[contains(.,'На почтовый адрес %s отправлено письмо со ссылкой для подтверждения регистрации')]";
	private Label registrationIsComplete = new Label(By.xpath("//span[contains(.,'Регистрация завершена')]"), "Регистрация завершена");
	private final int countOfSertificats = 1;
	private final int codeLength = 6;
	// Раздел "Регистрационные данные организации"
	private BasePartition partRegData = new BasePartition("//div[@class='%s']/table[%s]/tbody", "tablet", "Регистрационные данные организации");
	private final int fieldFullName = 1;
	// Классификационные признаки
	private TextBox okpoCodeTxb = new TextBox(By.id("okpoCode"), "Код ОКПО");
	private Link openOkpoCatalog = new Link(By.xpath("//img[contains(@onclick,'chooseOkpo.html')]"), "Открыть справочник ОКПО");
	private final BaseTable tableOkpo = new BaseTable("innertable_1", "", "");
	private final String columnOkatoCode = "Код по ОКАТО";
	private final String columnOktmoCode = "Код по ОКТМО";
	private final String columnOkfsCode = "Код по ОКФС";
	private final String columnOkopfCode = "Код по ОКОПФ";

	/** Возвращает полное наименование регистрируемой организации
	 * @return полное наименование
	 */
	public String getFullName(){
		String text = partRegData.getText(fieldFullName, "/span", "Полное наименование организации");
		return text;
	}

	/**
	 * Нажимает кнопку 'Далее' и ждет переключения на вкладку пользователь
	 */
	public final void clickNextBtn(){
		nextBtn.clickAndWait();
		selectedRegUserTab.waitAndAssertIsPresent();
	}

	/**
	 * Нажимает кнопку 'Зарегистрировать', обрабатывает появляющееся сообщение
	 * и ждет сообщения об отправке письма для подтверждения на указанный адрес
	 * @param email адрес элекстронной почты
	 */
	public final void zaregOrg(final String email){
		zaregistrirovat.clickAndWait();
		warningRegMessage.waitAndAssertIsPresent();
		logger.info("Сообщение при регистрации: " + warningRegMessage.getText());
		continueBtn.clickAndApproveSecurityWarning(countOfSertificats);
		browser.waitForPageToLoad();
		Label l = new Label(By.xpath(String.format(expectedRegText, email)), "Сообщение об отправке письма");
		l.waitAndAssertIsPresent();
		logger.info("Сообщение об отправке письма: " + l.getText());
		logger.info("Ожидание прихода письма: 2 минуты.");
	}

	/**
	 * Нажимает кнопку 'Зарегистрировать', и ждет сообщения об отправке письма
	 * для подтверждения на указанный адрес
	 * @param email адрес элекстронной почты
	 */
	public void zaregPolzovatela(String email){
		zaregistrirovat.clickAndWait();
		browser.waitForPageToLoad();
		Label l = new Label(By.xpath(String.format(expectedRegText, email)), "Сообdщение об отправке письма");
		l.waitAndAssertIsPresent();
	}

	/**
	 * Подключается к gmail почте, получает содержимое письма от указанного отправителя
	 * После удаляет это письмо
	 * @param email ящик
	 * @param password пароль к ящику
	 * @param expectedMessageSender отправитель
	 */
	public final void getConfirmMessageAndVerifyRegIsComplete(final String email, final String password, final String expectedMessageSender){
		GmailUtils gmail = new GmailUtils();
		String message = gmail.readerMessageFromSender(email, password, expectedMessageSender);
		String confirmUrl = message.substring(message.indexOf("http")).replace(".\r\n	", "").replace(".\r\n", "");
		logger.info("Ссылка для подтверждения регистрации: " + confirmUrl);
		browser.navigate(confirmUrl);
		registrationIsComplete.waitAndAssertIsPresent();
	}

	/** Возвращает код для подтверждения регистрации пользователя
	 * @param email почта
	 * @param password пароль
	 * @param expectedMessageSender ожидаемое сообщение
	 * @return код подтверждения
	 */
	public final String getUserCodeFromConfirmMessage(final String email, final String password, final String expectedMessageSender){
		GmailUtils gmail = new GmailUtils();
		String message = gmail.readerMessageFromSender(email, password, expectedMessageSender);
		logger.info("Содержимое сообщения: " + message);
		String code = message.substring(message.indexOf("код подтверждения:\r\n"), message.indexOf("код подтверждения:\r\n") + codeLength);
		logger.info("Код для подтверждения, полученный из сообщения: " + code);
		return code;
	}

	/** Выбирает первый код ОКПО из справочника
	 * @param okatoCode должен быть объектом StringBuilder, для инициализации его внутри метода
	 * @param oktmoCode должен быть объектом StringBuilder, для инициализации его внутри метода
	 * @param okfsCode должен быть объектом StringBuilder, для инициализации его внутри метода
	 * @param okopfCode должен быть объектом StringBuilder, для инициализации его внутри метода
	 * @return выбранный код окпо
	 */
	public String selectOkpoCode(StringBuilder okatoCode, StringBuilder oktmoCode, StringBuilder okfsCode, StringBuilder okopfCode){
		openOkpoCatalog.clickAndRepeatIfNewWindowNotAppeared(2);
		CatalogOkpoForm catalog = new CatalogOkpoForm();
		return catalog.selectFirstOkpoAndCloseCatalog(okatoCode, oktmoCode, okfsCode, okopfCode);
	}

	/** Устанавливает код ОКПО
	 * @param okpoCode код окпо
	 */
	public void setOkpoCode(String okpoCode){
		okpoCodeTxb.setText(okpoCode);
	}


	/** Проверяет добавленные классификационные признаки
	 * @param okpo код окпо
	 * @param okato код окато
	 * @param oktmo код октмо
	 * @param okfs код окфс
	 * @param okopf код окопф
	 */
	public void assertClassificationAttributes(String okpo, String okato, String oktmo, String okfs, String okopf){
		jassert.assertText("Код по ОКПО", okpo, okpoCodeTxb.getValue(), true);
		tableOkpo.assertTextInColumn(columnOkatoCode, okato, columnOkatoCode, okato);
		tableOkpo.assertTextInColumn(columnOktmoCode, oktmo, columnOkatoCode, okato);
		tableOkpo.assertTextInColumn(columnOkfsCode, okfs, columnOkatoCode, okato);
		tableOkpo.assertTextInColumn(columnOkopfCode, okopf, columnOkatoCode, okato);
	}

	/** Проверяет какой режим заполнения классификационных признаков выбран
	 * 1(false) - это раздельное заполнение окато, октмо, окопф, окфс
	 * 2(true) - это выбор ОКОП, а остальные данные подтягиваются автоматически
	 * @return выбран 2-ой режим?
	 */
	public Boolean isOKPOMode(){
		return openOkpoCatalog.isPresent();
	}
}
